package com.kurumi.autoprint.util;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.HttpHostConnectException;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.kurumi.autoprint.enums.ResponseStatusEnum;

public class YinlianPayUtil {
	private static final Logger log  = LoggerFactory.getLogger(YinlianPayUtil.class);
	
	public static Result send(String url,String authorization, String entity) throws Exception {
		CloseableHttpClient httpClient = null;
		HttpPost httpPost = null;
		CloseableHttpResponse response = null;
		String resStr = null;
		
		try {
				httpClient = HttpClients.createDefault();
				httpPost = new HttpPost(url);
				httpPost.addHeader("Authorization", authorization);
				StringEntity se = new StringEntity(entity, "UTF-8");
				se.setContentType("application/json");
				httpPost.setEntity(se);
				response = httpClient.execute(httpPost);
				
				int code = response.getStatusLine().getStatusCode();
				
				if (code == 200) {
					resStr = EntityUtils.toString(response.getEntity(), "UTF-8");
				}
				
				if (code == 404) {
					return new Result(false, ResponseStatusEnum.YING_LIAN_NO_CONNECT.getName(), null, 
							ResponseStatusEnum.YING_LIAN_NO_CONNECT.getValue());
				}
				
				if (StringUtils.isBlank(resStr)) {
					return new Result(false, "调用银联支援不存在返回code=" + code, ResponseStatusEnum.RESOURCE_NOT_EXIT.getValue());
				}
				
		} catch(HttpHostConnectException connectException) {
			log.error("调用银联生成二维码连接异常, exceptionMsg={}" + ExceptionUtil.getStackTrace(connectException));
			return new Result(false, ResponseStatusEnum.YING_LIAN_NO_CONNECT.getName(), null, 
					ResponseStatusEnum.YING_LIAN_NO_CONNECT.getValue());
		} catch (Exception e) {
			log.error("调用银联生成二维码异常, exceptionMsg={}" + ExceptionUtil.getStackTrace(e));
			return new Result(false, "调用银联生成二维码异常:" + ExceptionUtil.getStackTrace(e), null, 500);
		} finally {
			if (null != httpClient) {
				httpClient.close();
			}
			
			if (null != response) {
				response.close();
			}
		}
		
		return new Result(true, "成功", resStr, 200);
	}

	public static String getOpenBodySig(String appId, String appKey, String body) throws Exception {
		String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
		String nonce = UUID.randomUUID().toString().replace("-", "");
		// String timestamp ="20191217105731";
		// String nonce
		// ="56548739295648788745791425133429327818843849435659236726618617265657711657952724271549568584292395186895354815832918166775279458";
		byte[] data = body.getBytes("UTF-8");
		System.out.println("data:\n" + body);
		InputStream is = new ByteArrayInputStream(data);
		String bodyDigest = testSHA256(is);
		System.out.println("bodyDigest:\n" + bodyDigest);
		String str1_C = appId + timestamp + nonce + bodyDigest;

		System.out.println("str1_C:\n" + str1_C);

//        System.out.println("appKey_D:\n" + appKey);

		byte[] localSignature = hmacSHA256(str1_C.getBytes(), appKey.getBytes());
		// System.out.println(Arrays.toString(localSignature));
		String localSignatureStr = Base64.encodeBase64String(localSignature);
		System.out.println(
				"Authorization:\n" + "OPEN-BODY-SIG AppId=" + "\"" + appId + "\"" + ", Timestamp=" + "\"" + timestamp
						+ "\"" + ", Nonce=" + "\"" + nonce + "\"" + ", Signature=" + "\"" + localSignatureStr + "\"");
		return ("OPEN-BODY-SIG AppId=" + "\"" + appId + "\"" + ", Timestamp=" + "\"" + timestamp + "\"" + ", Nonce="
				+ "\"" + nonce + "\"" + ", Signature=" + "\"" + localSignatureStr + "\"");
	}

	private static String testSHA256(InputStream is) {
		try {
//            System.out.println(is.hashCode());
			return DigestUtils.sha256Hex(is);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static byte[] hmacSHA256(byte[] data, byte[] key) throws NoSuchAlgorithmException, InvalidKeyException {
		String algorithm = "HmacSHA256";
		Mac mac = Mac.getInstance(algorithm);
		mac.init(new SecretKeySpec(key, algorithm));
		return mac.doFinal(data);
	}
	
	
	/**
	 * 生成订单号
	 * @return
	 */
	public static String generateBillNo(String msgSrcId) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddmmHHssSSS");
		StringBuilder builder = new StringBuilder();
		if(StringUtils.isNotBlank(msgSrcId)) {
			builder.append(msgSrcId);
		}else {
			builder.append("6668");
		}
		
		String timeStamp = sdf.format(new Date());
		builder.append(timeStamp).append(StringUtil.rand());
		return builder.toString();
		
	}



}
